package com.atguigu.gulimall.product.service.impl;

import com.atguigu.common.constant.ProductConstant;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.atguigu.gulimall.product.dao.AttrGroupDao;
import com.atguigu.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.atguigu.gulimall.product.entity.AttrEntity;
import com.atguigu.gulimall.product.entity.AttrGroupEntity;
import com.atguigu.gulimall.product.service.AttrAttrgroupRelationService;
import com.atguigu.gulimall.product.service.AttrGroupService;
import com.atguigu.gulimall.product.service.AttrService;
import com.atguigu.gulimall.product.service.CategoryService;
import com.atguigu.gulimall.product.vo.AttrGroupRelationVO;
import com.atguigu.gulimall.product.vo.AttrGroupWithAttrsVO;
import com.atguigu.gulimall.product.vo.AttrVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private AttrAttrgroupRelationService attrAttrgroupRelationService;

    @Autowired
    private AttrService attrService;

    @Autowired
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new QueryWrapper<AttrGroupEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params, Long catelogId) {
        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<>();
        if (catelogId != 0) {
            wrapper.eq("catelog_id", catelogId);
        }
        String key = (String) params.get("key");
        if (StringUtils.isNotEmpty(key)) {
            wrapper.and(w -> w
                    .eq("attr_group_id", key)
                    .or()
                    .like("attr_group_name", key));
        }

        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                wrapper);
        return new PageUtils(page);
    }

    @Override
    public AttrGroupEntity getArrtGroupById(Long attrGroupId) {
        AttrGroupEntity attrGroupEntity = this.getById(attrGroupId);
        List<Long> catelogPath = categoryService.getCatelogPath(attrGroupEntity.getCatelogId());
        attrGroupEntity.setCatelogPath(catelogPath);
        return attrGroupEntity;
    }

    @Override
    public List<AttrEntity> listAttrOfAttrGroup(Long attrGroupId) {
        List<AttrAttrgroupRelationEntity> list = attrAttrgroupRelationService.list(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                .eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupId));
        List<Long> attrIds = list
                .stream()
                .map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(attrIds)) {
            return Collections.emptyList();
        }
        Collection<AttrEntity> attrEntities = attrService.listByIds(attrIds);
        return (List<AttrEntity>) attrEntities;
    }

    @Override
    public void deleteRelation(List<AttrGroupRelationVO> list) {
        List<AttrAttrgroupRelationEntity> relationEntityList = list
                .stream()
                .map(attrGroupRelationVO -> {
                    AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
                    BeanUtils.copyProperties(attrGroupRelationVO, relationEntity);
                    return relationEntity;
                })
                .collect(Collectors.toList());
        attrAttrgroupRelationDao.deleteRelation(relationEntityList);
    }

    @Override
    public PageUtils listAttrOfAttrGroupCategoryNoRef(Long attrGroupId, Map<String, Object> params) {
        AttrGroupEntity attrGroupEntity = this.getById(attrGroupId);

        // 已经被引用的的 基础属性id
        List<Long> referencedAttrIds = attrAttrgroupRelationService
                .list()
                .stream()
                .map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());

        // 查询当前属性分组的分类下的没有被引用的基础属性
        LambdaQueryWrapper<AttrEntity> wrapper = Wrappers
                .<AttrEntity>lambdaQuery()
                .eq(AttrEntity::getCatelogId, attrGroupEntity.getCatelogId())
                .eq(AttrEntity::getAttrType, ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())
                .notIn(!CollectionUtils.isEmpty(referencedAttrIds), AttrEntity::getAttrId, referencedAttrIds);
        String key = (String) params.get("key");
        if (StringUtils.isNotBlank(key)) {
            wrapper.and(attrEntityLambdaQueryWrapper -> attrEntityLambdaQueryWrapper
                    .eq(AttrEntity::getAttrId, key)
                    .or()
                    .like(AttrEntity::getAttrName, key));
        }
        // 加上模糊查询条件
        IPage<AttrEntity> page = attrService.page(
                new Query<AttrEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public List<AttrGroupWithAttrsVO> listAttrGroupWithAttrsByCatelogId(Long catelogId) {
        List<AttrGroupEntity> attrGroupEntities = this.list(Wrappers.<AttrGroupEntity>lambdaQuery()
                .eq(AttrGroupEntity::getCatelogId, catelogId));
        if (CollectionUtils.isEmpty(attrGroupEntities)) {
            return Collections.emptyList();
        }
        // 获取属性分组id集
        List<Long> attrGroupIds = attrGroupEntities
                .stream()
                .map(AttrGroupEntity::getAttrGroupId)
                .collect(Collectors.toList());
        // 查询属性分组集下的属性vo
        List<AttrVO> attrVOS = this.listAttrInAttrGroupIds(attrGroupIds);
        // 封装 AttrGroupWithAttrsVO 集合返回
        return attrGroupEntities
                .stream()
                .map(attrGroupEntity -> {
                    AttrGroupWithAttrsVO attrGroupWithAttrsVO = new AttrGroupWithAttrsVO();
                    BeanUtils.copyProperties(attrGroupEntity, attrGroupWithAttrsVO);
                    List<AttrVO> voList = attrVOS
                            .stream()
                            // 过滤出当前遍历属性分组下的 属性VO集合
                            .filter(attrVO -> attrGroupEntity.getAttrGroupId().equals(attrVO.getAttrGroupId()))
                            .collect(Collectors.toList());
                    attrGroupWithAttrsVO.setAttrs(voList);
                    return attrGroupWithAttrsVO;
                })
                .collect(Collectors.toList());
    }

    /**
     * 查询属性分组集下的属性vo
     * @param attrGroupIds
     * @return
     */
    private List<AttrVO> listAttrInAttrGroupIds(List<Long> attrGroupIds) {
        // 查询属性分组集下的所有 属性和属性分组关系
        List<AttrAttrgroupRelationEntity> relationEntities = attrAttrgroupRelationService.list(Wrappers
                .<AttrAttrgroupRelationEntity>lambdaQuery()
                .in(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupIds));
        if (CollectionUtils.isEmpty(relationEntities)) {
            return Collections.emptyList();
        }
        // 获取属性id,属性分组id的map
        Map<Long, Long> relationMap = relationEntities
                .stream()
                .collect(Collectors.toMap(AttrAttrgroupRelationEntity::getAttrId, AttrAttrgroupRelationEntity::getAttrGroupId));
        // 获取属性 属性分组集下的属性 id 集
        List<Long> attrIds = relationEntities
                .stream()
                .map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());
        // 查询 属性分组集下的 所有属性
        Collection<AttrEntity> attrEntities = attrService.listByIds(attrIds);
        // 封装属性VO集合
        return attrEntities
                .stream()
                .map(attrEntity -> {
                    AttrVO attrVO = new AttrVO();
                    BeanUtils.copyProperties(attrEntity, attrVO);
                    attrVO.setAttrGroupId(relationMap.get(attrVO.getAttrId()));
                    return attrVO;
                })
                .collect(Collectors.toList());
    }

}
